from qcloud_cos import CosConfig
from qcloud_cos import CosS3Client

from django.conf import settings
from qcloud_cos.cos_exception import CosServiceError


# 正常情况日志级别使用 INFO，需要定位时可以修改为 DEBUG，此时 SDK 会打印和服务端的通信信息
# logging.basicConfig(level=logging.INFO, stream=sys.stdout)


def create_bucket(bucket, region='ap-chengdu'):
    """
    创建桶
    :param region: 地区
    :param bucket: 桶名
    :return:
    """
    # 1. 设置用户属性, 包括 secret_id, secret_key, region等。Appid 已在 CosConfig 中移除，请在参数 Bucket 中带上 Appid。Bucket 由 BucketName-Appid 组成
    secret_id = settings.SECRET_COS_ID
    secret_key = settings.SECRET_COS_KEY
    region = region
    token = None
    scheme = 'https'

    config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)
    client = CosS3Client(config)

    response = client.create_bucket(
        Bucket=bucket,
        ACL='public-read',  # private 【私读写 / public-read【公读私写 / public-read-write 【公读写    三种格式
    )
    # 解决跨域的问题【加上跨域
    cors_config = {
        'CORSRule': [
            {
                'AllowedOrigin': '*',
                'AllowedMethod': ['PUT', 'GET', 'POST', 'DELETE', 'HEAD'],
                'AllowedHeader': '*',
                'ExposeHeader': '*',
                'MaxAgeSeconds': 500,

            }
        ]
    }
    client.put_bucket_cors(
        Bucket=bucket,
        CORSConfiguration=cors_config
    )


def upload_file(bucket, region, file_object, key):
    secret_id = settings.SECRET_COS_ID
    secret_key = settings.SECRET_COS_KEY
    region = region
    token = None
    scheme = 'https'
    config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)
    client = CosS3Client(config)

    response = client.upload_file_from_buffer(
        Bucket=bucket,  # 桶的名
        Body=file_object,  # 文件对象
        Key=key,  # 上传到桶后的文件名
    )

    # 上传成功后应该返回图片路径
    # https://wuping-1316848700.cos.ap-chengdu.myqcloud.com/xxw.jpg
    return f"https://{bucket}.cos.{region}.myqcloud.com/{key}"


def delete_file(bucket, region, key):
    secret_id = settings.SECRET_COS_ID
    secret_key = settings.SECRET_COS_KEY
    region = region
    token = None
    scheme = 'https'
    config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)
    client = CosS3Client(config)

    client.delete_object(
        Bucket=bucket,  # 桶的名
        Key=key,  # 文件名
    )


def check_file(bucket, region, key):
    """ 获取文件的etag """
    secret_id = settings.SECRET_COS_ID
    secret_key = settings.SECRET_COS_KEY
    region = region
    token = None
    scheme = 'https'
    config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)
    client = CosS3Client(config)

    data = client.head_object(
        Bucket=bucket,  # 桶的名
        Key=key,  # 文件名
    )

    return data


def delete_file_list(bucket, region, key_list):
    secret_id = settings.SECRET_COS_ID
    secret_key = settings.SECRET_COS_KEY
    region = region
    token = None
    scheme = 'https'
    config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)
    client = CosS3Client(config)

    objects = {
        "Quiet": "true",
        "Object": key_list,
    }

    client.delete_objects(
        Bucket=bucket,  # 桶的名
        Delete=objects
    )


def credential(bucket, region, ):
    """ cos获取上传临时凭证 """
    # 生成一个临时凭证，并给前端返回
    # 1. 安装一个生成临时凭证python模块   pip install -U qcloud-python-sts
    # 2. 写代码
    from sts.sts.Sts import Sts
    config = {
        # 临时密钥有效时长，单位是秒（30分钟=1800秒）
        'duration_seconds': 1800,
        # 固定密钥 id
        'secret_id': settings.SECRET_COS_ID,
        # 固定密钥 key
        'secret_key': settings.SECRET_COS_KEY,
        # 换成你的 bucket
        'bucket': bucket,
        # 换成 bucket 所在地区
        'region': region,
        # 这里改成允许的路径前缀，可以根据自己网站的用户登录态判断允许上传的具体路径
        # 例子： a.jpg 或者 a/* 或者 * (使用通配符*存在重大安全风险, 请谨慎评估使用)
        'allow_prefix': '*',
        # 密钥的权限列表。简单上传和分片需要以下的权限，其他权限列表请看 https://cloud.tencent.com/document/product/436/31923
        'allow_actions': [
            # 'name/cos:PostObject',  # 上传
            # 'name/cos:DeleteObject',
            # "name/cos:UploadPart",
            # "name/cos:UploadPartCopy",
            # "name/cos:CompleteMultipartUpload",
            # "name/cos:AbortMultipartUpload",
            "*",
        ],

    }
    sts = Sts(config)
    result_dict = sts.get_credential()
    return result_dict


def delete_bucket1(bucket, region):
    """ 错误的 删除桶 """
    # 删除所有文件
    # 删除所有碎片
    # 删除桶
    secret_id = settings.SECRET_COS_ID
    secret_key = settings.SECRET_COS_KEY
    region = region
    token = None
    scheme = 'https'
    config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key, Token=token, Scheme=scheme)
    client = CosS3Client(config)

    # part_objects = client.list_objects(bucket)
    # print(part_objects)
    # print(dict)
    # 找到桶中的文件 & 删除
    while True:
        part_objects = client.list_objects(bucket)
        contents = part_objects.get('Contents')  # true 桶中代表还有文件
        if not contents:
            break
        # 批量删除
        delete_list = []
        delete_list.index = list(range(1, len(delete_list)))
        for item in contents:
            delete_list.append({"Key": item['Key']})

        objects = {
            "Quiet": "true",
            "Object": delete_list
        }
        # objects = {
        #     "Quiet": "true",
        #     "Object": [{'Key': item["Key"]} for item in contents]
        # }
        client.delete_object(bucket, objects)
        # 判断有没有被截断 最大一次获取1000
        if part_objects['isTruncated'] == 'false':
            break

    # 找到碎片 & 碎片 【和删除文件差不多
    while True:
        part_uploads = client.list_multipart_uploads(bucket)
        uploads = part_uploads.get('Upload')
        # 判断是否还有碎片
        if not uploads:
            break
        for item in uploads:
            client.abort_multipart_upload(bucket, item['Key'], item['UploadId'])

        if part_uploads['isTruncated'] == 'false':
            break

    # 删除桶
    client.delete_bucket(bucket)


def delete_bucket(bucket_name, region):
    """ 删除 项目桶 """
    secret_id = 'AKID0qVK4f4FCtOgkbGm5A2g5GE2f7RYR5Ug'
    secret_key = '2sVdbMyPdfT5WmpfIm6D8pOmwsNtCJEx'

    config = CosConfig(Region=region, SecretId=secret_id, SecretKey=secret_key)
    client = CosS3Client(config)

    # 根据腾讯cos的要求，删除桶必须前清空桶
    try:  # 防止删除不存在的桶cos报错
        # 1. 删除所有的桶文件
        while True:
            part_objects = client.list_objects(bucket_name)

            # 已经删除完毕，获取不到值
            contents = part_objects.get('Contents')
            if not contents:
                break

            # 批量删除
            objects = {
                "Quiet": "true",
                "Object": [{'Key': item["Key"]} for item in contents]
            }
            client.delete_objects(bucket_name, objects)

            if part_objects['IsTruncated'] == "false":
                break

        # 2. 删除所有的桶碎片
        while True:
            part_uploads = client.list_multipart_uploads(bucket_name)
            uploads = part_uploads.get('Upload')
            if not uploads:
                break
            for item in uploads:
                client.abort_multipart_upload(bucket_name, item['Key'], item['UploadId'])
            if part_uploads['IsTruncated'] == "false":
                break

        # 3. 删除空桶
        client.delete_bucket(bucket_name)
    except CosServiceError as e:
        pass
